package com.leonzx.base.service.system;

import com.leonzx.base.config.quartz.BaseJob;
import com.leonzx.base.dao.system.JobAndTriggerDAO;
import com.leonzx.base.entity.system.JobAndTrigger;
import com.leonzx.base.service.BaseService;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author:梁亮
 * @Description:
 * @Date: 2018/7/2 17:32
 */
@Service
public class JobService extends BaseService {

    //加入Qulifier注解，通过名称注入bean
    @Autowired
    @Qualifier("Scheduler")
    private Scheduler scheduler;

    @Autowired
    private JobAndTriggerDAO jobAndTriggerDAO;

    /**
     * 创建定时任务
     *
     * @param jobClassName
     * @param jobGroupName
     * @param cronExpression
     * @throws Exception
     */
    public void jobAdd(String jobClassName, String jobGroupName, String cronExpression) throws Exception {
        jobAdd(jobClassName, jobGroupName, cronExpression, new HashMap<>());
    }

    public void jobAdd(String jobClassName, String jobGroupName, String cronExpression, Map<String, String> datas) throws Exception {
        jobAdd(jobClassName, jobClassName, jobGroupName, "", cronExpression, datas);
    }

    /**
     * @param jobName
     * @param jobClassName
     * @param jobGroupName
     * @param description
     * @param cronExpression
     * @param datas
     * @throws Exception
     */
    public void jobAdd(String jobName, String jobClassName, String jobGroupName, String description, String cronExpression, Map<String, String> datas) throws Exception {
        // 启动调度器
        scheduler.start();
        //构建job信息
        JobBuilder jobBuilder = JobBuilder.newJob(getClass(jobClassName).getClass()).withIdentity(jobName, jobGroupName);
        for (String key : datas.keySet()) {
            jobBuilder.usingJobData(key, datas.get(key));
        }
        jobBuilder.withDescription(description);
        JobDetail jobDetail = jobBuilder.build();
        //表达式调度构建器(即任务执行的时间)
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
        //按新的cronExpression表达式构建一个新的trigger
        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobClassName, jobGroupName).withSchedule(scheduleBuilder).build();
        try {
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (ObjectAlreadyExistsException e) {
            throw e;
        } catch (SchedulerException e) {
            throw e;
        }
    }

    /**
     * 暂停定时任务
     *
     * @param jobClassName
     * @param jobGroupName
     * @throws Exception
     */
    public void jobPause(String jobClassName, String jobGroupName) throws Exception {
        scheduler.pauseJob(JobKey.jobKey(jobClassName, jobGroupName));
    }

    /**
     * 恢复定时任务
     *
     * @param jobClassName
     * @param jobGroupName
     * @throws Exception
     */
    public void jobResume(String jobClassName, String jobGroupName) throws Exception {
        scheduler.resumeJob(JobKey.jobKey(jobClassName, jobGroupName));
    }

    /**
     * 重新刷新定时任务
     *
     * @param jobClassName
     * @param jobGroupName
     * @param cronExpression
     * @throws Exception
     */
    public void jobUpdate(String jobClassName, String jobGroupName, String cronExpression) throws Exception {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(jobClassName, jobGroupName);
            // 表达式调度构建器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            // 按新的cronExpression表达式重新构建trigger
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
            // 按新的trigger重新设置job执行
            scheduler.rescheduleJob(triggerKey, trigger);
        } catch (SchedulerException e) {
            logger.error("更新定时任务失败", e);
            throw new Exception("更新定时任务失败");
        }
    }

    /**
     * 删除任务
     *
     * @param jobClassName
     * @param jobGroupName
     * @throws Exception
     */
    public void jobDelete(String jobClassName, String jobGroupName) throws Exception {
        scheduler.pauseTrigger(TriggerKey.triggerKey(jobClassName, jobGroupName));
        scheduler.unscheduleJob(TriggerKey.triggerKey(jobClassName, jobGroupName));
        scheduler.deleteJob(JobKey.jobKey(jobClassName, jobGroupName));
    }

    public static BaseJob getClass(String classname) throws Exception {
        Class<?> class1 = Class.forName(classname);
        return (BaseJob) class1.newInstance();
    }

    public List<JobAndTrigger> getJobAndTriggers() {
        return jobAndTriggerDAO.findJobAndTriggerDetails();
    }
}
